package main

import "fmt"

func modifyAge(age int) {
	// golang中值引用的参数传递是值拷贝（值传递），即会拷贝传入对象的为一份新的值作为参数
	fmt.Println("method before", age, &age) // method before 18 0x1400012a020
	age = 20
	fmt.Println("method after", age, &age) // method after 20 0x1400012a020
}

func modifyAgePoint(age *int) {
	// golang中指针类型的参数传递是指针类型变量的拷贝，可以简单理解为还是传的age的内存地址过来，本质是上指针的值传递，看上去像引用传递
	fmt.Println("point before", *age, age, &age) // point before 18 0x140000b4008 0x140000ae020
	*age = 30                                    // 修改了age内存地址指向的值，也就等于修改了age变量所引用的值 ，修改之后指针变量指向的内存地址还是不变，变的只是内存地址指向的值
	fmt.Println("point after", *age, age, &age)  // point after 30 0x140000b4008 0x140000ae020
}

func main() {
	age := 18
	fmt.Println("main before", age, &age) // main before 18 0x1400012a008
	modifyAge(age)
	fmt.Println("main after:", age, &age) // main before 18 0x1400012a008
	modifyAgePoint(&age)
	fmt.Println("main after:", age, &age) // main after: 30 0x140000b4008
}

/**
所以说：
- 如果传参数是值类型，方法中参数的值修改后，原来的值不变，因为参数是值拷贝
- 如果参数是指针类型，方法中指针指向的值发生变化后，外部的原来的变量和变量指针指向的值也会发生变化，本质上是指针类型的值拷贝，也是属于值传递

也就是说，当你需要在函数中通过形参改变实参的值时，需要使用指针类型的参数。

什么情况下使用指针？
从以上指针的详细分析中，我们可以总结出指针的两大好处：
1.可以修改指向数据的值；
2.在变量赋值，参数传值的时候可以节省内存。
*/
